/**
 * @author Tobias Boehm
 *
 * 06.06.2011
 */
package org.anddev.andengine.extension.tbsengine.match.gamestate;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.anddev.andengine.extension.tbsengine.faction.AbsBaseFaction;
import org.anddev.andengine.extension.tbsengine.match.AbsClientMatch;
import org.anddev.andengine.extension.tbsengine.match.AbsStep;
import org.anddev.andengine.extension.tbsengine.match.Round;
import org.anddev.andengine.extension.tbsengine.match.Turn;
import org.anddev.andengine.extension.tbsengine.message.server.ingame.AbsServerMatchReconnectRequestReplyMessage;
import org.anddev.andengine.extension.tbsengine.team.Team;

/**
 * This class extends {@link AbsGlobalGameState} and
 * represents an abstract client version of a global game
 * state. You should extend this class and implement its
 * abstract methods in order to create a global
 * game state class for the client side of your game.
 * You may use an instance of your implementation
 * of this class in your implementation of {@link AbsClientMatch}.
 * 
 * @author Tobias Boehm
 *
 * @param <ServerJoinRequestReplyMessageClass> - A implementation of {@link AbsServerMatchReconnectRequestReplyMessage} its instances contains all necessary information to initialize the player game states.
 * @param <ClientMatchClass> - An implementation of {@link AbsClientMatch}.
 * @param <PlayerGameStateClass> - An implementation of {@link AbsPlayerGameState}.
 * @param <BaseFactionClass> - An implementation of {@link AbsBaseFaction}
 */
public abstract class AbsClientGlobalGameState<ServerJoinRequestReplyMessageClass extends AbsServerMatchReconnectRequestReplyMessage<?>,
									   ClientMatchClass extends AbsClientMatch<PlayerGameStateClass,?,?,?>,
									   PlayerGameStateClass extends AbsPlayerGameState<BaseFactionClass>,
									   BaseFactionClass extends AbsBaseFaction>

									   extends AbsGlobalGameState<ClientMatchClass, PlayerGameStateClass, BaseFactionClass> {

	/**
	 * A reference to a ServerJoinRequestReplyMessage which
	 * contains all all necessary information to initialize
	 * the player game states.
	 */
	protected final ServerJoinRequestReplyMessageClass mMessage; 
	
	/**
	 * With this constructor you can create and
	 * initialized  a new client game state.
	 * 
	 * @param pMatch - The corresponding match. 
	 * @param pMessage - The message from the game server with all necessary information to initialize the player game states.
	 */
	public AbsClientGlobalGameState(final ClientMatchClass pMatch, final ServerJoinRequestReplyMessageClass pMessage) {
		super(pMatch);
		
		this.mMessage = pMessage;
		
		this.initializeGlobalGameState();
	}
	
	/**
	 * This method should return a map of player IDs
	 * and corresponding game state objects.
	 * You should find all necessary info inside <code>pMessage</code>.
	 * 
	 * 
	 * @param pMessage - A message from the game server with all necessary information to initialize the player game states.
	 * @param pAvailableTeams - A map with all available teams.
	 * 
	 * @return - A map of of player IDs and corresponding game state objects.
	 */
	protected abstract Map<UUID, PlayerGameStateClass> createClientPlayerIDsGameStatesMap(final ServerJoinRequestReplyMessageClass pMessage, final Map<Integer,Team> pAvailableTeams);
	
	
	@Override
	public void onTurnCompleted(Turn pTurn) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onStepCompleted(AbsStep pStep) {
		// TODO Auto-generated method stub
		
	}

	

	@Override
	public void onRoundStarted(Round<PlayerGameStateClass> pRound) {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected Map<UUID, PlayerGameStateClass> createPlayerIDsGameStatesMap() {
		
		return this.createClientPlayerIDsGameStatesMap(this.mMessage,this.mTeams);
	}
	
	@Override
	protected Map<Integer, Team> createTeams() {
		
		final HashMap<Integer, Team> teamsMap = new HashMap<Integer, Team>();
		
		for(Integer currentTeamID : this.mMessage.getGameStateIDteamIDmap().values()){
			
			teamsMap.put(currentTeamID, new Team(currentTeamID));
		}
		
		return teamsMap;
	}
}
